#pragma once

#include <core/types.h>

#define IRQ_NONE       0
#define IRQ_HANDLED    1

#define IRQ_TYPE_NONE		    0x00000000
#define IRQ_TYPE_EDGE_RISING    0x00000001
#define IRQ_TYPE_EDGE_FALLING   0x00000002
#define IRQ_TYPE_EDGE_BOTH      (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
#define IRQ_TYPE_LEVEL_HIGH	    0x00000004
#define IRQ_TYPE_LEVEL_LOW      0x00000008
#define IRQ_TYPE_SENSE_MASK     0x0000000f
#define IRQ_TYPE_PROBE          0x00000010


struct IrqDesc;

struct IntCtrl
{
	void (*Ack)(UINT32);
	void (*Mask)(UINT32);
	void (*MaskAck)(UINT32);
	void (*Unmask)(UINT32);
	int	 (*SetTrigger)(UINT32, UINT32);
};


typedef	void (*IRQ_HANDLE)(struct IrqDesc *, UINT32);

struct IrqDesc
{
	IRQ_HANDLE	     IrqHandle;
	struct IntCtrl	*pIntCtrl;
	struct IrqDev	*pIrqDev;
};


typedef int (*DEV_IRQ_HANDLE)(void *);

struct IrqDev
{
	void          *pDevice;
	DEV_IRQ_HANDLE DevHandle;
	struct IrqDev *pNextDev;
};


void IrqHandleLevel(struct IrqDesc *pDesc, UINT32 nIrq);

void IrqHandleEdge(struct IrqDesc *pDesc, UINT32 nIrq);

void IrqHandleSimple(struct IrqDesc *pDesc, UINT32 nIrq);

void IrqSetHandler(UINT32 nIrq, IRQ_HANDLE IrqHandle, int isChained);

int RegisterIsr(UINT32 nIrq, DEV_IRQ_HANDLE DevHandle, void *pDev);

